home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume20 / cgrep2 / part01 next >
Encoding:
Text File  |  1991-07-10  |  8.7 KB  |  309 lines

  1. Newsgroups: comp.sources.misc,comp.lang.perl
  2. From: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
  3. Subject:  v20i092:  cgrep2 - context grep in perl, version 2, Part01/01
  4. Message-ID: <1991Jul10.020543.17296@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: fe1e3f8fb41eb9bf8df21657e63d1554
  6. Date: Wed, 10 Jul 1991 02:05:43 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
  10. Posting-number: Volume 20, Issue 92
  11. Archive-name: cgrep2/part01
  12. Supersedes: cgrep: Volume 20, Issue 88
  13.  
  14. A few days ago I posted 'cgrep', Version 1.
  15. I got some feedback since then and worked over it;
  16. here is an upgrade. I think this will do for a while.
  17.  
  18. HERE WE GO:
  19.  
  20. The following is version 2 of cgrep (a Perl script).
  21. cgrep is a grep that gives you a number of context lines along with the 
  22. matching line.
  23.  
  24. The following changes occured in respect to version 1:
  25.  
  26.   I added options
  27.     -i (ignore case)
  28.     -c (count matches also)
  29.  
  30.   documented option
  31.     -e (end the list of options)
  32.  
  33.   removed a bug in option
  34.     -n which gave wrong line numbers in precontext
  35.  
  36.   and polished all a bit.
  37.  
  38. For exact usage, see the message in the body of the script.
  39. You will probably have to edit the first line of the script,
  40. to tell it where your 'perl' resides.
  41.  
  42.    Lutz
  43.  
  44. Lutz Prechelt   (++49/721/608-4317,  FAX: ++49/721/697760)
  45. Institut fuer Programmstrukturen und Datenorganisation
  46. Universitaet Karlsruhe;  D-7500 Karlsruhe 1;  Germany
  47. prechelt@ira.uka.de  or  prechelt!ira.uka.de@relay.csnet
  48. ----------------------------- cut here -----------------------------------
  49. #! /bin/sh
  50. # This is a shell archive.  Remove anything before this line, then unpack
  51. # it by saving it into a file and typing "sh file".  To overwrite existing
  52. # files, type "sh file -c".  You can also feed this as standard input via
  53. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  54. # will see the following message at the end:
  55. #        "End of shell archive."
  56. # Contents:  cgrep
  57. # Wrapped by prechelt@Djibouti on Mon Jul  8 12:49:40 1991
  58. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  59. if test -f 'cgrep' -a "${1}" != "-c" ; then 
  60.   echo shar: Will not clobber existing file \"'cgrep'\"
  61. else
  62. echo shar: Extracting \"'cgrep'\" \(5904 characters\)
  63. sed "s/^X//" >'cgrep' <<'END_OF_FILE'
  64. X#!/tools/bin/perl
  65. X#
  66. X#    Copyright (C) 1991 by Lutz Prechelt, Karlsruhe
  67. X#
  68. X#    This program is free software; you can redistribute it and/or modify
  69. X#    it under the terms of the GNU General Public License as published by
  70. X#    the Free Software Foundation; either version 1, or (at your option)
  71. X#    any later version.
  72. X#    This program is distributed in the hope that it will be useful,
  73. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  74. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  75. X#    GNU General Public License for more details.
  76. X#    If you don't have a copy of the GNU General Public License write to
  77. X#    Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  78. X
  79. X# Version:     2,  Patchlevel 0
  80. X# Author:      Lutz Prechelt (prechelt@ira.uka.de), 23.03.91
  81. X# Correction   by Sridhar Vasudevan, 03.07.91
  82. X# Last Change: Lutz Prechelt, 04.07.91
  83. X#
  84. X# Usage: see message at "die" below.
  85. X
  86. X#---------- constants:
  87. X$infinity         = 10000;
  88. X
  89. X#---------- Variables:
  90. X$delimiterstring  = "-----------\n";
  91. X$matches          = 0;
  92. X$precontext       = 2;
  93. X$postcontext      = 2;
  94. X$wrong_option     = 0;
  95. X
  96. X#---------- boolean Options:
  97. X$paragraphmode    = 0;
  98. X$count_matches    = 0;
  99. X$ignorecase       = 0;
  100. X$withlinenumber   = 0;
  101. X$withfilename     = 0;
  102. X$reversemode      = 0;
  103. X
  104. X# $endpara = '\S.*\n';
  105. X
  106. X#---------- Subroutines:
  107. X
  108. Xsub match_found {
  109. X  #bad style: uses the global variables $ignorecase, $reversemode, $cur, $pat
  110. X  if ($ignorecase != 0) {
  111. X    ($reversemode == 1 ? $cur !~ /$pat/io : $cur =~ /$pat/io);
  112. X  }
  113. X  else {
  114. X    ($reversemode == 1 ? $cur !~ /$pat/o : $cur =~ /$pat/o);
  115. X  }
  116. X}
  117. X
  118. Xsub showline {
  119. X  if ($withfilename != 0) {
  120. X    printf ("\"%s\"", $ARGV);
  121. X  }
  122. X  if ($withfilename != 0 && $withlinenumber != 0) {
  123. X    print ",";
  124. X  }
  125. X  if ($withlinenumber != 0) {
  126. X    printf ("%4d", $_[1]);
  127. X  }
  128. X  if ($withfilename != 0 || $withlinenumber != 0) {
  129. X    print ": ";
  130. X  }
  131. X  print ($_[0]);
  132. X}
  133. X
  134. X
  135. X#---------- Process the Options:
  136. Xdo {
  137. X  $something_done = 1;
  138. X  if ($ARGV[0] =~ /^-(\d+)$/) {
  139. X    $precontext = $postcontext = $1;
  140. X    shift;
  141. X  }
  142. X  elsif ($ARGV[0] =~ /^-(\d+)[\,\+\/\;](\d+)$/) {
  143. X    $precontext  = $1;
  144. X    $postcontext = $2;
  145. X    shift;
  146. X  }
  147. X  elsif ($ARGV[0] =~ /^-d$/ && $#ARGV > 0) {
  148. X    $delimiterstring = $ARGV[1];
  149. X    $delimiterstring =~ s/\\n/\n/o;
  150. X    shift; shift;
  151. X  }
  152. X  elsif ($ARGV[0] =~ /^-d(.*)$/) {
  153. X    $delimiterstring = $1;
  154. X    $delimiterstring =~ s/\\n/\n/o;
  155. X    shift;
  156. X  }
  157. X  elsif ($ARGV[0] =~ /^-c$/) {
  158. X    $count_matches = 1;
  159. X    shift;
  160. X  }
  161. X  elsif ($ARGV[0] =~ /^-h$/) {
  162. X    $withfilename = 1;
  163. X    shift;
  164. X  }
  165. X  elsif ($ARGV[0] =~ /^-i$/) {
  166. X    $ignorecase = 1;
  167. X    shift;
  168. X  }
  169. X  elsif ($ARGV[0] =~ /^-n$/) {
  170. X    $withlinenumber = 1;
  171. X    shift;
  172. X  }
  173. X  elsif ($ARGV[0] =~ /^-p$/) {
  174. X    $paragraphmode = 1;
  175. X    shift;
  176. X  }
  177. X  elsif ($ARGV[0] =~ /^-v$/) {
  178. X    $reversemode = 1;
  179. X    shift;
  180. X  }
  181. X  elsif ($ARGV[0] =~ /^-e$/) { # end options (for expressions starting
  182. with - )
  183. X    $something_done = 0;
  184. X    shift;
  185. X  }
  186. X  elsif ($ARGV[0] =~ /^-/) {
  187. X    printf ("don't know option '%s'\n", $ARGV[0]);
  188. X    $wrong_option = 1;
  189. X    $something_done = 0;
  190. X    shift;
  191. X  }
  192. X  else {
  193. X    $something_done = 0;
  194. X  }
  195. X} while ($something_done);
  196. X
  197. X
  198. X#---------- Usage message:
  199. Xif ($#ARGV == -1 || $wrong_option) {
  200. X  die "
  201. X   Usage: cgrep [-pre[,post]] [-p] [-v] [-c] [-h] [-n] [-d string] 
  202. X                [-e] pattern [file...]
  203. X
  204. X   cgrep is a context grep. It displays more than the one matching line for
  205. X   every match (2 before and 2 after as default).
  206. X
  207. X   -3   means display 3 lines before and 3 lines after the match (e.g.)
  208. X   -5,12  means display 5 lines before the match and 12 lines after (e.g.)
  209. X   -p   means display only as much of the context as belongs to the
  210. X        current paragraph. (paragraphs bounded by empty lines)
  211. X   -v   means invert search (display nomatches)
  212. X   -c   means display number of matching lines at the end of run
  213. X   -h   means toggle display filename before every line
  214. X   -i   means ignore case when matching the regexp
  215. X   -n   means display line number before every line
  216. X   -d string  means use string as the output delimiter string
  217. X   -e   means end options (i.e. now comes the pattern, 
  218. X                           for patterns starting with - )
  219. X   pattern  is a Perl regular expression (you better quote it !)
  220. XExiting";
  221. X}
  222. X
  223. X
  224. Xif (length (@ARGV) > 1) {
  225. X  $withfilename = !$withfilename;
  226. X}
  227. X
  228. X
  229. X#---------- Get the pattern and protect the delimiter.
  230. X$pat = shift;
  231. X$pat =~ s#/#\\/#g;
  232. X
  233. X
  234. X#---------- current line will always be at end of array, i.e.
  235. $ary[$currentpre]
  236. X$_ = <>;
  237. Xpush(@ary,$_);
  238. X$currentpre = 0;
  239. X
  240. X#---------- do the search
  241. X# use @ary as a silo, shifting and pushing.
  242. X# the length of the @ary at any time is $currentpre + 1
  243. X# the current line is @ary[$currentpre], the postcontext is not held in @ary.
  244. X$seq = 0;
  245. X$lastoutput = $infinity;  #last output is infinitely many lines ago
  246. X$cur = @ary[0];       #current line
  247. Xwhile ($cur) {  #as long as there is something to look at
  248. X  if (&match_found()) {
  249. X    $matches++;
  250. X    if ($lastoutput <= $postcontext) {
  251. X      &showline ($cur, $.);
  252. X    }
  253. X    else {
  254. X      print $delimiterstring if ($seq++ && $precontext + $postcontext > 0);
  255. X      $lineno = $. - $#ary;
  256. X      foreach $line (@ary) {
  257. X        &showline ($line, $lineno++);
  258. X      }
  259. X    }
  260. X    $lastoutput = 0;
  261. X  }
  262. X  elsif (($cur !~ /\S.*\n/o && $paragraphmode == 1) || eof) {
  263. #paragraph/file end
  264. X    for (; $currentpre >= 0; $currentpre--) {
  265. X      shift (@ary);
  266. X    }
  267. X    $lastoutput = $infinity;
  268. X    close (ARGV) if (eof);
  269. X  }
  270. X  elsif ($lastoutput <= $postcontext) {     #another line of postcontext
  271. X    &showline ($cur, $.);
  272. X  }
  273. X  #goto next line of input:
  274. X  $lastoutput++;
  275. X  $_ = <> if $_;
  276. X  push(@ary,$_); 
  277. X  if ($currentpre < $precontext) {
  278. X    $currentpre++;
  279. X  }
  280. X  else {
  281. X    shift(@ary);
  282. X  }
  283. X  $cur = $ary[$currentpre];
  284. X}
  285. X
  286. X
  287. X#---------- perhaps display number of matches:
  288. Xif ($count_matches != 0) {
  289. X  printf ("%d\n", $matches);
  290. X}
  291. X
  292. X
  293. END_OF_FILE
  294. if test 5904 -ne `wc -c <'cgrep'`; then
  295.     echo shar: \"'cgrep'\" unpacked with wrong size!
  296. fi
  297. chmod +x 'cgrep'
  298. # end of 'cgrep'
  299. fi
  300. echo shar: End of shell archive.
  301. exit 0
  302.  
  303. exit 0 # Just in case...
  304. -- 
  305. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  306. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  307. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  308. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  309.